#pragma once

#include <iostream>
#include <boost/shared_ptr.hpp>
#include "types.h"
#include "imglib/imageclass.h"

namespace icache {

class item_id
{
public:
	virtual ~item_id() { }
	virtual bool equal(const item_id &) const = 0;
	///user friendly name, that may be given to a file
	virtual string name() const = 0;
	virtual void serialize(std::ostream &) const = 0;
	///return true if load(...) method is implemented, otherwise users should use request(...)
	virtual bool loadable() const = 0;
	virtual void load(byte_image & im) const = 0;
	///return true if request(...) method is implemented, otherwise users should use load(...)
	virtual bool requestable() const = 0;
	virtual void request() const = 0; ///< the method loads item also, but it places it in cache(s) instead of direct returning
	///return true if normal image loading is typically slower than loading from disc cache
	virtual bool cache_on_disc() const = 0;
};

typedef boost::shared_ptr<item_id> item_id_sptr;

class item_id_deserializer
{
public:
	virtual ~item_id_deserializer() { }
	//return null ptr if parsing fails
	virtual item_id_sptr parse(std::istream &) const = 0;
};

struct cached_image;
typedef boost::shared_ptr<cached_image> cached_image_sptr;

struct cached_image {
	cached_image() { }
	cached_image(item_id_sptr const & i, byte_image const & m = byte_image()) : id(i), im(m) { }
	static cached_image_sptr create(item_id_sptr const & i, byte_image const & m = byte_image())
		{ return cached_image_sptr(new cached_image(i, m)); }
	size_t size() { return im.bytes(); }
public:
	item_id_sptr id;
	byte_image im;
};

} //namespace icache
